/**************************************************************
 * @file     Circular_buffer.h
 * @brief    提供创建环形缓冲区的接口和操作函数
 * @author   Ruilist
 * @date     2025-08-09
 * @version  V1.0.0
 * @copyright Copyright (c) 2025
 *
 * @note     1 tab = 4 space
 *
 * @par 日志:
 * - V1.0.0 2025-08-09 Ruilist
 *   提供创建环形缓冲区的接口和操作函数
 **************************************************************/

#ifndef __CIRCULAR_BUFFER_H__
#define __CIRCULAR_BUFFER_H__

//******************************** Includes *********************************//

#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "elog.h"

//******************************** Includes *********************************//

//******************************** Defines **********************************//

#define CIRCULAR_BUFFER_SIZE 10  // 环形缓冲区大小

typedef uint8_t data_type_t;  // 环形缓冲区中数据类型

/**
 * @struct circular_buffer_t
 * @brief 用于描述环形缓冲区的结构
 *
 * head-环形缓冲区的头计数值;
 *
 * tail-环形缓冲区的尾计数值;
 *
 * data[CIRCULAR_BUFFER_SIZE]-数组与数组大小;
 */
typedef struct
{
    uint32_t    head;
    uint32_t    tail;
    data_type_t data[CIRCULAR_BUFFER_SIZE];
} circular_buffer_t;

/**
 * @enum Circular_buffer_status_t
 * @brief 枚举函数操作的返回值
 *
 * CIRCULAR_BUFFER_OK-0；
 *
 * CIRCULAR_BUFFER_ERROR-1；
 */
typedef enum
{
    CIRCULAR_BUFFER_OK    = 0,  // 函数操作成功
    CIRCULAR_BUFFER_ERROR = 1,  // 函数操作失败
    INCOME_PARAM_ERROR    = 2,  // 传入参数错误
    NO_MEMORY_ERROR       = 3,  // 内存不足
    BUFFER_STORED         = 4,  // 缓冲区中有数据
    BUFFER_IS_EMPTY       = 5,  // 缓冲区为空
    BUFFER_IS_FULL        = 7,  // 缓冲区为满
} Circular_buffer_status_t;

//******************************** Defines **********************************//

//******************************** Declaring ********************************//

/**
 * @brief   创建环形缓冲区
 *
 * @param[in] circular_buffer_t**p_buffer 通过传入地址指针获得环形缓冲区的地址
 *
 * @return Circular_buffer_status_t
 *
 * @retval CIRCULAR_BUFFER_OK 创建缓冲区成功
 * @retval CIRCULAR_BUFFER_ERROR 创建缓冲区失败
 * @retval INCOME_PARAM_ERROR 传入参数错误
 * @retval NO_MEMORY_ERROR 内存不足
 */
Circular_buffer_status_t create_circular_buffer( circular_buffer_t **p_buffer );

/**
 * @brief   获得缓冲区的存储状态
 *
 * @param[in] circular_buffer_t*p_buffer 通过传入地址指针获得环形缓冲区的地址
 *
 * @return Circular_buffer_status_t
 *
 * @retval INCOME_PARAM_ERROR 传入参数错误
 * @retval BUFFER_STORED 缓冲区中有数据
 * @retval BUFFER_IS_EMPTY 缓冲区为空
 * @retval BUFFER_IS_FULL 缓冲区为满
 * @retval CIRCULAR_BUFFER_ERROR 函数操作失败
 */
Circular_buffer_status_t circular_buffer_status( circular_buffer_t *p_buffer );


/**
 * @brief   向缓冲区中插入一个数据
 *
 * @param[in] circular_buffer_t*p_buffer 通过传入地址指针获得环形缓冲区的地址
 * @param[in] data_type_t-data 要插入的数据
 *
 * @return Circular_buffer_status_t
 * @retval INCOME_PARAM_ERROR 传入参数错误
 * @retval CIRCULAR_BUFFER_OK 插入数据成功
 * @retval BUFFER_IS_FULL 缓冲区为满
 */
Circular_buffer_status_t insert_circular_buffer( circular_buffer_t *p_buffer, data_type_t data );

/**
 * @brief   向缓冲区中取出一个数据
 *
 * @param[in] circular_buffer_t*p_buffer 通过传入地址指针获得环形缓冲区的地址
 * @param[in] data_type_t*p_data 取出数据后要存入的地址
 *
 * @return Circular_buffer_status_t
 *
 * @retval INCOME_PARAM_ERROR 传入参数错误
 * @retval CIRCULAR_BUFFER_OK 取出数据成功
 * @retval BUFFER_IS_EMPTY 缓冲区为空
 */
Circular_buffer_status_t read_circular_buffer( circular_buffer_t *p_buffer, data_type_t *p_data );

/**
 * @brief   获得缓冲区中头位置
 *
 * @param[in] circular_buffer_t*p_buffer 通过传入地址指针获得环形缓冲区的地址
 * @param[in] uint32_t*p_head 取出数据后要存入的地址
 *
 * @return Circular_buffer_status_t
 *
 * @retval INCOME_PARAM_ERROR 传入参数错误
 * @retval CIRCULAR_BUFFER_OK 取出数据成功
 */
Circular_buffer_status_t get_head_circular_buffer( circular_buffer_t *p_buffer, uint32_t *p_head );

/**
 * @brief   使缓冲区中头位置偏移
 *
 * @param[in] circular_buffer_t*p_buffer 通过传入地址指针获得环形缓冲区的地址
 * @param[in] uint32_t offset 取出数据后要存入的地址
 *
 * @return Circular_buffer_status_t
 *
 * @retval INCOME_PARAM_ERROR 传入参数错误
 * @retval CIRCULAR_BUFFER_OK 函数操作成功
 * @retval BUFFER_IS_FULL 缓冲区已满
 */
Circular_buffer_status_t head_offset_circular_buffer( circular_buffer_t *p_buffer, uint32_t offset );

//******************************** Declaring ********************************//

#endif  // End of __CIRCULAR_BUFFER_H__